﻿#region imports

using System;
using System.Collections;
using System.Data.Services;
using System.Net;
using System.Web;
using Codeplex.ODataTFS.Model.ExpressionVisitors;
using Microsoft.TeamFoundation;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

#endregion

namespace Codeplex.ODataTFS.Model.Serialization
{
	public class TFSBaseProxy : IDisposable
	{
		protected TfsConnection TfsConnection { get; private set; }

		protected IDictionary Cache
		{
			get { return HttpContext.Current.Items; }
		}

		public TFSBaseProxy(Uri tfsCollection, ICredentials credentials)
		{
			TfsConnection = new TfsTeamProjectCollection(tfsCollection, credentials);
		}

		public static bool CollectionExists(Uri collectionUri, ICredentials credentials, out bool isAuthorized)
		{
			TfsTeamProjectCollection collection = null;

			try
			{
				collection = new TfsTeamProjectCollection(collectionUri, credentials);
				collection.EnsureAuthenticated();
				isAuthorized = true;

				return true;
			}
			catch (TeamFoundationServerUnauthorizedException)
			{
				isAuthorized = false;

				return true;
			}
			catch
			{
				isAuthorized = false;

				return false;
			}
			finally
			{
				if (collection != null)
				{
					collection.Dispose();
				}
				collection = null;
			}
		}

		protected WorkItemCollection QueryWorkItems(string wiql)
		{
			WorkItemStore workItemServer = TfsConnection.GetService<WorkItemStore>();

			try
			{
				Query q = new Query(workItemServer, wiql, null, false);

				return q.RunQuery();
			}
			catch (ValidationException ex)
			{
				throw new DataServiceException(500, "Internal Server Error", ex.Message, "en-US", ex);
			}
		}

		protected Uri GetTfsWebAccessArtifactUrl(Uri uri)
		{
			var hyperlinkService = TfsConnection.GetService<TswaClientHyperlinkService>();

			// For CodePlex TFS we need to convine the base URL with the path and query.
			return new Uri(TfsConnection.Uri, hyperlinkService.GetArtifactViewerUrl(uri).PathAndQuery);
		}

		protected virtual string GetFilterNodeKey(FilterNode rootFilterNode)
		{
			string filterNodeKey = string.Empty;
			if (rootFilterNode != null)
			{
				foreach (FilterNode f in rootFilterNode)
				{
					filterNodeKey = filterNodeKey + f.Key.ToLower() + ":" + f.Value.Trim().ToLower() + ":" + f.Sign.ToString() + "-";
				}
			}

			return filterNodeKey;
		}

		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}


		protected virtual void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (TfsConnection != null)
				{
					TfsConnection.Dispose();
					TfsConnection = null;
				}
			}
		}
	}
}
